package com.szxx.suit;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.szxx.domain.Cards;

/**
 * 默认的牌型分析服务 <br>
 * 子类覆盖请使用 @primary
 *
 * @author Ambrose
 */
@Component
@SuppressWarnings("rawtypes")
public class SuitAnalysisService implements ISuitAnalysisService {

	private static Logger logger = LoggerFactory.getLogger(SuitAnalysisService.class);

	/** 牌型规则集合（从大到小排列） */
	List<AbstractSuitAnalyzer> suitAnalyzers = new LinkedList<AbstractSuitAnalyzer>();

	/**
	 * 添加一种新的牌型处理器 <br>
	 * register 操作仅允许在服务器启动时，运行时严禁改变
	 * 
	 * @param newSuitFactory
	 */
	@Override
	public void register(AbstractSuitAnalyzer newSuitFactory) {
		logger.error("register processor for {}", newSuitFactory.getClass().getSimpleName());
		suitAnalyzers.add(newSuitFactory);
		Collections.sort(suitAnalyzers, SUIT_COMPARATOR_DESC_BY_COUNT);
	}

	@Override
	public AbstractSuitAnalyzer getSuitAnalyzer(AbstractSuitType type) {
		for (AbstractSuitAnalyzer analyzer : suitAnalyzers) {
			if (analyzer.getSuitType() == type) {
				return analyzer;
			}
		}
		return null;
	}
	
	@Override
	public List<AbstractSuitType> listAbstractSuitType(boolean desc) {
		List<AbstractSuitType> typeList = new LinkedList<AbstractSuitType>();
		for (AbstractSuitAnalyzer abstractSuitAnalyzer : suitAnalyzers) {
			if (abstractSuitAnalyzer.getSuitType() != null) {
				typeList.add(abstractSuitAnalyzer.getSuitType());
			}
		}
		Collections.sort(typeList, TYPE_COMPARATOR_ASC);
		if (desc) {
			Collections.reverse(typeList);
		}
		return typeList;
	}

	@Override
	public List<AbstractSuitType> listPossibleTypes(Cards cards, AbstractSuitTerm term, boolean desc) {
		return listPossibleTypes(cards, term, null, desc);
	}

	@Override
	public List<AbstractSuitType> listPossibleTypes(Cards cards, AbstractSuitTerm term, AbstractSuitType type, boolean desc) {
		List<AbstractSuitType> typeList = new ArrayList<AbstractSuitType>();
		for (int i = 0, size = suitAnalyzers.size(); i < size; i++) {
			AbstractSuitAnalyzer suitAnalyzer = suitAnalyzers.get(i);
			if (type == null) { // type == null 默认没有限制
				if (suitAnalyzer.match(cards, term)) {
					typeList.add(suitAnalyzer.getSuitType());
				}
			} else {
				// 要求大于suitAnalyzer.getSuitType() 大于或等于 type 这里不能用 <= 0 作判定 
				if (type.compareTo(suitAnalyzer.getSuitType()) < 0 
						|| type.equals(suitAnalyzer.getSuitType())) {
					if (suitAnalyzer.match(cards, term)) {
						typeList.add(suitAnalyzer.getSuitType());
					}
				}
			}
		}
		Collections.sort(typeList, TYPE_COMPARATOR_ASC);
		if (desc) {
			Collections.reverse(typeList);
		}
		return typeList;
	}

	@Override
	public AbstractAnalysisResult analysis(Cards cards, AbstractSuitTerm term, AbstractSuitType type) {
		if (cards !=null && type != null) {
			AbstractSuitAnalyzer analyzer = getSuitAnalyzer(type);
			if (analyzer != null && analyzer.match(cards, term)) {
				analyzer.analysize(cards, term);
			}
		}
		return cards.getResult();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Cards> analysisLaizi(Cards cards, AbstractSuitTerm term, AbstractSuitType type) {
		List<Cards> result = new LinkedList<Cards>();
		if (cards != null && type != null) {
			AbstractSuitAnalyzer analyzer = getSuitAnalyzer(type);
			if (analyzer != null && analyzer.match(cards, term)) {
				try {
					result.addAll(analyzer.analysizeLaizi(cards, term, false));
				} catch (Exception e) {
					logger.error("!!!!!!!!!!!!!"+Thread.currentThread().toString(), e);
				}
			}
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Cards> listInTypePossibleCards(Cards cards, AbstractSuitTerm term, AbstractSuitType type) {
		List<Cards> result = new LinkedList<Cards>();
		if (cards != null && type != null) {
			AbstractSuitAnalyzer analyzer = getSuitAnalyzer(type);
			if (analyzer != null) {
				result.addAll(analyzer.listPossibleCards(cards, term));
			}
		}
		return result;
	}

	
}
